﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Yoda.Classes
{
	public class YodaCalc
	{

		public YodaCalc()
		{

		}

		/// <summary>
		/// Updates the result.
		/// </summary>
		/// <param name="firstCouplePoint">The first couple point.</param>
		/// <param name="current">The current.</param>
		/// <param name="replay">if set to <c>true</c> [replay].</param>
		/// <returns>true if the result updated, false if result restore needed</returns>
		public bool UpdateResult(bool? firstCouplePoint, Result current, bool replay)
		{
			if (firstCouplePoint.HasValue)
			{
				if (firstCouplePoint.Value)
				{
					//increase FIRST doubles points
					current.FirstDoublesPoint = increasePoint(current.FirstDoublesPoint, current.SecondDoublesPoint, current.IsInTieBreak);
					checkGame(current);
				}
				else
				{
					//increase SECOND doubles points
					current.SecondDoublesPoint = increasePoint(current.SecondDoublesPoint, current.FirstDoublesPoint, current.IsInTieBreak);
					checkGame(current);
				}
				current.LastPoint = firstCouplePoint.Value;
			}
			else
			{
				//when replay the point
				if (replay)
				{
					if (current.LastPoint.HasValue)
					{
						if (current.FirstDoublesPoint == "0" && current.SecondDoublesPoint == "0")
						{
							return false;
						}
						else
						{
							if (current.LastPoint.Value)
							{
								//decrease point of FIRST doubles
								if (current.FirstDoublesPoint == "0" && current.SecondDoublesPoint == "0")
								{
									return false;
								}
								decreasePoint(current.FirstDoublesPoint, current.IsInTieBreak);

							}
							else
							{

								//decrease point of SECOND doubles
								decreasePoint(current.SecondDoublesPoint, current.IsInTieBreak);

							}
						}
					}

				}
				current.LastPoint = null;
			}
			return true;

		}

		/// <summary>
		/// Check the games when points are set
		/// </summary>
		/// <param name="result">An object</param>
		/// <returns>A void</returns>
		private void checkGame(Result pointResult)
		{
			if (pointResult.FirstDoublesPoint == "W")
			{
				pointResult.FirstDoublesGame++;
				pointResult.FirstDoublesPoint = "0";
				pointResult.SecondDoublesPoint = "0";
			}

			if (pointResult.SecondDoublesPoint == "W")
			{
				pointResult.SecondDoublesGame++;
				pointResult.FirstDoublesPoint = "0";
				pointResult.SecondDoublesPoint = "0";
			}

			if (pointResult.FirstDoublesGame==7 || ( pointResult.FirstDoublesGame==6 && pointResult.GameDifference>1))
			{
				pointResult.Finished =true;
			}

			if (pointResult.SecondDoublesGame==7 || ( pointResult.SecondDoublesGame==6 && pointResult.GameDifference>1))
			{
				pointResult.Finished =true;
			}

		}

		private string increasePoint(string actualPoint, string pointEnemy, bool tieBreak)
		{
			if (tieBreak)
			{
				//just increase the number
				int point = Int16.Parse(actualPoint) + 1;
				int enemyPoint = Int16.Parse(pointEnemy);


				if (point > 6 && Math.Abs(point - enemyPoint) >= 2)
				{
					//set to W when this was the game-winner point
					return "W";
				}
				else
				{
					return point.ToString();
				}
			}
			else
			{
				switch (actualPoint)
				{
					case "0":
						return "15";
					case " 0":
						return "15";
					case "15":
						return "30";
					case "30":
						return "40";
					case "40":
						if (pointEnemy == "40")
						{
							return " A";
						}
						else
						{
							//set to W when this was the game-winner point
							return "W";
						}
					case " A":
						{
							return "W";
						}
					default:
						return "--";
				}
			}

		}

		private string decreasePoint(string actualPoint, bool tieBreak)
		{
			if (tieBreak)
			{
				//just decrease the number
				int point = Int16.Parse(actualPoint) - 1;

				return point.ToString();

			}
			else
			{
				switch (actualPoint)
				{
					//todo decrease game
					case "0":
						return "--";
					case " 0":
						return "--";
					case "15":
						return " 0";
					case "30":
						return "15";
					case "40":
						return "30";
					case " A":
						{
							return "40";
						}
					default:
						return "--";

				}
			}

		}

	}


}
